package com.chixing.service.impl;

import com.alibaba.fastjson.JSON;
import com.chixing.mapper.CarMapper;
import com.chixing.mapper.ShopMapper;
import com.chixing.pojo.Car;
import com.chixing.pojo.CarExample;
import com.chixing.pojo.ESCarShop;
import com.chixing.pojo.Shop;
import com.chixing.service.ElasticSearchService;
import com.chixing.util.ServerResult;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class ElasticSearchServiceImpl implements ElasticSearchService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private CarMapper carMapper;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    //1.解析数据放入es索引当中
    @Override
    public Boolean parseContent() throws IOException {

        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 9201, "http")));


        List<Shop> shopList = shopMapper.selectByExample(null);

        //把查询到的数据放入es中
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("1m");

        List<ESCarShop> esCarShopList = new ArrayList<>();


        for (Shop shop : shopList) {
            CarExample example = new CarExample();
            example.createCriteria().andShopIdEqualTo(shop.getShopId());
            List<Car> carList = carMapper.selectByExample(example);
//            System.out.println("所查询到到车辆列表" + carList);
            if (carList != null && carList.size() > 0) {
                for (Car car : carList) {
                    ESCarShop esCarShop = new ESCarShop(car.getCarId(), car.getShopId(), car.getCarBrand(), car.getCarName(), car.getCarType(), car.getCarDailyPrice(), shop.getShopAddress(), car.getCarImage(), shop.getShopName());
                    System.out.println(esCarShop);
                    esCarShopList.add(esCarShop);
                }
            }
        }

        for (int i = 0; i < esCarShopList.size(); i++) {
            System.out.println(esCarShopList.get(i));
            bulkRequest.add(
                    new IndexRequest("escarshop").source(JSON.toJSONString(esCarShopList.get(i)), XContentType.JSON).id("" + esCarShopList.get(i).getCarId())
            );
        }


        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

        System.out.println(bulk);
        return !bulk.hasFailures();
    }

    //    2.获取这些数据实现搜索功能  List<Map<String,Object>>
    @Override
    public ServerResult searchPage(String keyWord, int pageNo) throws IOException {
        if (pageNo <= 1) {
            pageNo = 1;
        }
        //条件搜索
        SearchRequest searchRequest = new SearchRequest("escarshop");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        //分页
        sourceBuilder.from(pageNo - 1);
        sourceBuilder.size(3);

        //精准匹配
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("carBrand", keyWord))
                .should(QueryBuilders.matchQuery("carName", keyWord))
                .should(QueryBuilders.matchQuery("carType", keyWord))
                .should(QueryBuilders.matchQuery("shopAddress", keyWord))
                .should(QueryBuilders.matchQuery("shopName", keyWord));

        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));


        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("carBrand").field("carName").field("carType");
        //highlightBuilder.requireFieldMatch(false);//多个高亮显示
        highlightBuilder.preTags("<span style = 'color:red'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("searchResponse : " + searchResponse);
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        //解析结果
        for (SearchHit documentFieles : searchResponse.getHits().getHits()) {
            Map<String, HighlightField> highlightFields = documentFieles.getHighlightFields();
            HighlightField carBrand = highlightFields.get("carBrand");
            HighlightField carName = highlightFields.get("carName");
            HighlightField carType = highlightFields.get("carType");

            Map<String, Object> sourceAsMap = documentFieles.getSourceAsMap();//原来的结果
            //解析高亮的字段,将原来的字段换为我们高亮的字段即可！
            if (carBrand != null) {
                Text[] fragments = carBrand.fragments();
                String newCarBrand = "";
                for (Text text : fragments) {
                    newCarBrand += text;
                }
                sourceAsMap.put("carBrand", newCarBrand);//高亮字段替换掉原来的内容即可
            }

            if (carName != null) {
                Text[] fragments = carName.fragments();
                String newCarName = "";
                for (Text text : fragments) {
                    newCarName += text;
                }
                sourceAsMap.put("carName", newCarName);//高亮字段替换掉原来的内容即可
            }

            if (carType != null) {
                Text[] fragments = carType.fragments();
                String newCarType = "";
                for (Text text : fragments) {
                    newCarType += text;
                }
                sourceAsMap.put("carType", newCarType);//高亮字段替换掉原来的内容即可
            }

            list.add(sourceAsMap);

        }

        Page<ESCarShop> page = PageHelper.startPage(pageNo, 3);
        PageInfo pageInfo = page.toPageInfo();
        pageInfo.setList(list);
        System.out.println("total:" + pageInfo.getTotal());
        System.out.println("pages:" + pageInfo.getPages());

        System.out.println(list);

        if (list != null && list.size() > 0) {
            return ServerResult.getSussess(pageInfo);
        } else {
            return ServerResult.getFail("没有匹配的车辆");
        }


//        return list;
    }

}
